<template>

    <div class="max-width">
        <h1>
            mysql_dump
        </h1>
        <div class="main">
            <item v-for="(v,k) in def" :value="v" @changed="change_handler" :key="k"
                  :parent="def"></item>
        </div>
        <div class="main">
            <button @click="ok_click()" style="padding:5px 10px;">生成</button>
        </div>
        <div v-html="result" class="res" ref="res"></div>
    </div>

</template>

<script type="text/ecmascript-6">
    import item from "../common/item"

    export default {
        components: {item},
        data: function () {
            return {
                def: {},
                template: "",
                result: ""
            }
        },
        created() {

        },
        mounted() {
            this.init();
        },
        methods: {
            initDef(def) {
                for (var key in def) {
                    var value = def[key];
                    if (value && value.Type == "string") {
                        value = {remark: value};
                    }
                    value = Object.assign({
                        group: false,
                        items: [],
                        must: false,
                        mutex: "",
                        dependency: "",
                        format: "key + '=' + value",
                        value: "",
                        type: null,
                        override: "",
                        data: [],
                        label: key,
                        ignore: false
                    }, value);

                    def[key] = value;

                    if (value.group) {
                        this.initDef(value.items);
                        continue;
                    }

                    if (!value.type) {
                        if (value.value.Type == "boolean") {
                            value.type = Boolean
                        } else if (value.value.Type == "array") {
                            value.type = Array
                        } else {
                            value.type = String
                        }
                    }
                }
            },
            init() {
                var def = {
                    //https://blog.csdn.net/loiterer_y/article/details/85091798
                    // "--print-defaults":"打印程序参数列表并退出.",
                    "--host": {must: true, remark: "要连接的远程主机IP"},
                    "database": {
                        remark: "数据库",
                        value: "",
                        must: true,
                        ignore: true
                    },
                    "--user": {value: "root", remark: "连接MySQL的用户名", must: true},
                    "--password": {value: "", remark: "连接数据库的密码", must: true},
                    "--tables": {
                        value: [],
                        format: "key + ' ' + value.join(' ')",
                        remark: "覆盖--databases (-B)参数,指定需要导出的表名。每个表同时指定数据库和表名，多个表名用空格连接",
                        mutex: "--ignore-table",
                        override: "--databases"
                    },
                    "--ignore-table": {
                        value: [],
                        format: "value.map(v=>' ' + key + ' ' + v).join(' ')",
                        remark: "不导出指定表。指定忽略多个表时，需要重复多次，每次一个表。每个表必须同时指定数据库和表名。",
                        mutex: "--tables",
                        override: "--databases"
                    },
                    "--routines": {value: true, remark: "导出保存的routine（存储过程和函数）"},
                    "--port": {value: "3306", remark: "端口号"},
                    "--protocol": {value: "tcp", remark: "协议"},

                    "tab": {
                        group: true,
                        items: {
                            "--tab": {value: "", must: true, remark: "为每个表在给定路径创建tab分割的文本文件"},
                            "--fields-enclosed-by": {
                                value: "\"",
                                remark: "字段包裹符.与--tab选项一起使用",
                                dependency: "--tab"
                            },
                            // "--fields-optionally-enclosed-by": {
                            //     value: "\"",
                            //     remark: "输出文件中的各个字段用给定字符选择性包裹。与--tab选项一起使用",
                            //     dependency: "--tab"
                            // },
                            "--fields-terminated-by": {
                                value: ",",
                                remark: "字段分割符.与--tab选项一起使用",
                                dependency: "--tab"
                            },
                        }
                    },

                    "--where": "只导出符合where条件的数据",
                    "--xml": "导出XML格式.",
                    "--comments": {value: true, remark: "将注释导入到dump文件中"},
                    "--no-create-db": {value: false, remark: "不导出建库语句"},
                    "--no-create-info": {value: false, remark: "不导出建表语句"},
                    "--no-data": {value: false, remark: "不导出表数据"},
                    "--no-tablespaces": {value: false, remark: "不导入表空间信息"},
                    "--order-by-primary": {value: true, remark: "导出每个表的数据行时按照表的主键或者第一个唯一字段排序"},

                    "--add-drop-database": {value: false, remark: "在CREATE DATABASE前添加DROP DATABASE语句"},
                    "--add-drop-table": {value: false, remark: "在CREATE TABLE前添加DROP TABLE语句"},
                    "--add-drop-user": {value: false, remark: "在CREATE USER前添加DROP USER语句"},
                    "--add-drop-trigger": {value: false, remark: "在CREATE TRIGGER前添加DROP TRIGGER语句"},
                    "--add-locks": {value: false, remark: "在每个表导出时添加LOCK TABLES并且之后进行UNLOCK TABLES"},

                    "--compatible": {
                        type: Radio,
                        data: "ansi,mysql323,mysql40,postgresql,oracle,mssql,db2,maxdb,no_key_options,no_tables_options,no_field_options".split(","),
                        value: "",
                        remark: "导出的数据将与其它类型数据库或旧版本的MySQL兼容"
                    },
                    "--complete-insert": {value: true, remark: "使用完整的包含列名的插入语句"},
                    "--compress": {value: true, remark: "在客户端与服务器间压缩传递所有的信息"},
                    "--create-options": {value: true, remark: "在CREATE TABLE语句中包含所有MySQL表特性选项"},

                    // "--no-defaults":"不要从任何选项文件读取默认选项，登录文件除外",
                    "--default-character-set": {value: "utf8", remark: "默认字符集"},
                    "--defaults-extra-file": "读取全局文件后读取此文件",
                    "--defaults-file": "只加载指定的配置文件",
                    // "--delete-master-logs":{value:false,remark:"在master备份后删除日志"},
                    "--extended-insert": {value: true, remark: "使用多行插入语句"},

                    "--flush-logs": {value: true, remark: "在开始导出前刷新日志"},
                    "--flush-privileges": {value: false, remark: "在导出数据库后，执行FLUSH PRIVILEGES"},
                    "--force": {value: false, remark: "在导出表的过程中忽略出现的SQL错误"},
                    "--hex-blob": {value: false, remark: "使用十六进制格式导出二进制字符串字段"},

                    "--include-master-host-port": {
                        value: false,
                        remark: "在--dump-slave产生的CHANGE MASTER TO..语句中增加MASTER_HOST=<host>，MASTER_PORT=<port>"
                    },
                    "--insert-ignore": {value: false, remark: "用INSERT IGNORE替代INSERT"},
                    "--lock-all-tables": {value: false, remark: "提交请求锁定所有数据库中的所有表，以保证数据的一致性。这是一个全局读锁，并且自动关闭"},
                    "--lock-tables": {value: false, remark: "在dump表之前锁表"},
                    "--log-error-file": "导出警告和错误信息到指定文件",
                    "--master-data": {value: false, remark: "该选项将binlog的位置和文件名追加到输出文件中"},

                    "--quick": {value: false, remark: "不缓冲查询，直接导出到标准输出"},
                    "--quote-names": {value: true, remark: "使用 ` 引起表和列名"},
                    "--replace": {value: false, remark: "用REPLACE取代INSERT语句"},
                    "--set-charset": {
                        value: true,
                        remark: "添加SET NAMES default_character_set到输出文件",
                        mutex: "--skip-set-charset"
                    },
                    "--single-transaction": {
                        value: false,
                        remark: "选项在导出数据之前提交一个BEGIN SQL语句，BEGIN 不会阻塞任何应用程序且能保证导出时数据库的一致性状态。它只适用于多版本存储引擎，仅InnoDB。本选项和–lock-tables 选项是互斥的，因为LOCK TABLES 会使任何挂起的事务隐含提交。要想导出大表的话，应结合使用–quick 选项。"
                    },
                    "--skip-add-drop-table": {value: false, remark: "不在CREATE TABLE前添加DROP TABLE语句"},
                    "--skip-add-locks": {value: false, remark: "导出时不加锁"}
                };

                this.initDef(def);

                this.def = def;
            },
            change_handler(p, k, v) {
                p[k] = v;
            },
            getParameters(p) {
                p = p || this.def;
                var ret = [];
                for (var k in p) {
                    var item = p[k];
                    if (item.group) {
                        ret.pushAll(this.getParameters(item.items));
                        continue;
                    }
                    if (item.ignore) {
                        continue;
                    }
                    var value = item.value;
                    if (jv.isNull(value)) {
                        continue;
                    }
                    if (value === "") {
                        continue;
                    }

                    if (value === false) {
                        continue;
                    }

                    if ((value instanceof Array) && !value.length) {
                        continue;
                    }

                    if (item.format) {
                        var v = eval("(function(key,value,def){return " + item.format + "})").call(p, k, value);
                        ret.push({key: k, value: v});
                    } else {
                        ret.push({key: k, value: k + "=" + value});
                    }
                }

                return ret;
            },
            getDefItem(key, p) {
                p = p || this.def;
                for (var k in p) {
                    var item = p[k];
                    if (k == key) return item;
                    if (item.group) {
                        item = this.getDefItem(key, item.items);
                        if (item) {
                            return item;
                        }
                    }
                }
            },
            ok_click() {

                var parameters = this.getParameters();

                var pKeys = parameters.map(it => it.key);

                var removeKeys = [];
                parameters.forEach(item => {
                    var def_item = this.getDefItem(item.key);
                    if (def_item.dependency && !pKeys.includes(def_item.dependency)) {
                        removeKeys.push(item.key);
                    }
                });

                parameters = parameters.removeItem(it => removeKeys.includes(it.key));


                // var fileName = this.def["--host"].value + "." + this.def["--databases"].value + "." + Date.now().toDateString("yyMMdd.HHmm") + ".sql";
                // fileName = fileName.replace(/ /g, '');

                this.result = "mysqldump " + parameters.map(it => it.value).join(" ") + " " + this.def["database"].value;

                this.$nextTick(() => {
                    var range = document.createRange();
                    range.selectNodeContents(this.$refs.res);
                    var selection = window.getSelection();
                    selection.removeAllRanges();
                    selection.addRange(range)
                });
            }
        }
    }
</script>

<style scoped>
    >>> .kv {
        margin: 10px;
        display: flex;
    }

    >>> .kv .k {
        display: inline-block;
        text-align: right;
        min-width: 160px;
    }

    >>> .kv .v {
        display: flex;
        flex: 1;
    }

    >>> .kv input {
        padding: 3px 5px;
        flex: 1;
    }

</style>
